/*
		ServEngine framework library
		A library to fast develop JEE online applications
	
		Copyright 2008 José Ignacio de Córdoba Álvaro

		Licensed under the Apache License, Version 2.0 (the "License");
		you may not use this file except in compliance with the License.
		You may obtain a copy of the License at

				http://www.apache.org/licenses/LICENSE-2.0

		Unless required by applicable law or agreed to in writing, software
		distributed under the License is distributed on an "AS IS" BASIS,
		WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
		See the License for the specific language governing permissions and
		limitations under the License.
	
		Jose Ignacio de Cordoba Alvaro
		http://ignacio.decordoba.com
*/

package com.servengine.portal;

import com.servengine.user.ExtraUserdataField;

import com.servengine.user.Role;
import com.servengine.user.User;

import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.ManyToMany;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Transient;
import javax.persistence.CascadeType;

@Entity
@NamedQueries ({
	@NamedQuery(name = "Portal.findBySearchstring", query = "select o from Portal o where lower(o.id) like :searchstring and lower(o.description) like :searchstring"),
	@NamedQuery(name = "Portal.findByHomeurl", query = "select o from Portal o where o.homeurl = :homeurl"),
	@NamedQuery(name = "Portal.findAll", query = "select o from Portal o "),
	@NamedQuery(name = "Portal.getUserCount", query = "select count(users) from Portal as p join p.users as users WHERE p.id = :portalid"),
	@NamedQuery(name = "Portal.getPortalCount", query = "select count(*) from Portal p")
})

public class Portal implements java.io.Serializable, java.lang.Comparable<Portal>
{
	public static String EMAIL_PROPERTY_NAME = "Portal.email";
	public static String GUEST_USER_ID_PROPERTY_NAME = "Portal.guestUserid";
	public static String ADMIN_ROLE_NAME_PROPERTY_NAME = "Portal.adminRoleName";
	private static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(Portal.class.getName());
	String id, homeurl, description, locale;//, newuserlegaltexturl, csshref;
//	String textcolor, htextcolor, textcolor2, htextcolor2, bgcolor, pbgcolor, bgcolor2, pbgcolor2;
	boolean userSelfSignup, newUserNotification,requiresSignupConfirmation;
	Date lastAccessed;
	int sessionRememberDays;
	Set<ExtraUserdataField> extraUserdataFields;
	Set<Property> properties;
	Set<Component> actions;
	Set<User> users;
	Set<Role> roles;

	public Portal() {}

	public Portal(String portalid)
	{
		extraUserdataFields = new HashSet<ExtraUserdataField>();
	  properties = new HashSet<Property>();
	  actions = new HashSet<Component>();
	  users = new HashSet<User>();
	  roles = new HashSet<Role>();
		id = portalid;
	}

	public Portal(String portalid, String locale)
	{
		this(portalid);
		this.locale=locale;
	}

	public Portal(String portalid, String homeurl, String description, String locale)
	{
		this(portalid,locale);
		this.homeurl=homeurl;
		this.description=description;
	}
	public boolean equals(Object o)
	{
		return id.equals(((Portal)o).getId());
	}

	public int compareTo(Portal o)
	{
		return id.compareTo(o.getId());
	}

	@Id
	public String getId()
	{
		return id;
	}

	public Date getLastAccessed()
	{
		return lastAccessed;
	}

	public String getHomeurl()
	{
		return homeurl;
	}

	public void setHomeurl(String value)
	{
		homeurl = value;
	}

	@Lob
	public String getDescription()
	{
		return description;
	}

	public void setDescription(String value)
	{
		description = value;
	}

	public String getLocale()
	{
		return locale;
	}

	public void setLocale(String value)
	{
		locale = value;
	}

/*	public String getNewuserlegaltexturl()
	{
		return newuserlegaltexturl;
	}

	public void setNewuserlegaltexturl(String value)
	{
		newuserlegaltexturl = value;
	}

	public java.lang.String getHtextcolor()
	{
		return htextcolor;
	}

	public void setHtextcolor(String value)
	{
		htextcolor = value;
	}

	public java.lang.String getBgcolor()
	{
		return bgcolor;
	}

	public void setBgcolor(String value)
	{
		bgcolor = value;
	}

	public java.lang.String getPbgcolor()
	{
		return pbgcolor;
	}

	public void setPbgcolor(String value)
	{
		pbgcolor = value;
	}

	public java.lang.String getTextcolor()
	{
		return textcolor;
	}

	public void setTextcolor(String value)
	{
		textcolor = value;
	}

	public java.lang.String getHtextcolor2()
	{
		return htextcolor2;
	}

	public java.lang.String getBgcolor2()
	{
		return bgcolor2;
	}

	public java.lang.String getPbgcolor2()
	{
		return pbgcolor2;
	}

	public java.lang.String getTextcolor2()
	{
		return textcolor2;
	}

	public java.lang.String getImgsurl()
	{
		return imgsurl;
	}

	public void setHtextcolor2(String value)
	{
		htextcolor2 = value;
	}

	public void setBgcolor2(String value)
	{
		bgcolor2 = value;
	}

	public void setPbgcolor2(String value)
	{
		pbgcolor2 = value;
	}

	public void setTextcolor2(String value)
	{
		textcolor2 = value;
	}

	public void setImgsurl(String value)
	{
		imgsurl = value;
	}
 */
	public boolean isUserSelfSignup()
	{
		return userSelfSignup;
	}

	public void setUserSelfSignup(boolean value)
	{
		userSelfSignup = value;
	}

	public int getSessionRememberDays()
	{
		return sessionRememberDays;
	}

	public void setSessionRememberDays(int value)
	{
		sessionRememberDays = value;
	}

	@Transient
	public boolean isRememberSession()
	{
		return sessionRememberDays > 0;
	}

	public boolean isNewUserNotification()
	{
		return newUserNotification;
	}

	public void setNewUserNotification(boolean value)
	{
		newUserNotification = value;
	}

	@OneToMany(mappedBy="portal",fetch=FetchType.EAGER,cascade={CascadeType.ALL})//TODO Pasar a LAZY
	public Set<ExtraUserdataField> getExtraUserdataFields()
	{
		return extraUserdataFields;
	}

	public void setExtraUserdataFields(Set<ExtraUserdataField> data)
	{
		extraUserdataFields = data;
	}

	@Transient
	public Map<String, ExtraUserdataField> getExtraUserdataFieldsMap()
	{
		Map<String, ExtraUserdataField> map = new HashMap<String, ExtraUserdataField>();
		for (ExtraUserdataField field: extraUserdataFields)
			map.put(field.getName(), field);
		return map;
	}

/*	public List<Category> getCategories()
	{
		return categories;
	}

	public void setCategories(List<Category> categories)
	{
		this.categories = categories;
	}

	public void addCategory(Category category)
	{
		categories.add(category);
	}

	public void removeCategory(Category category)
	{
		categories.remove(category);
	}
*/
//TODO He tenido que borrar el removeProperty por que no iba ¿y esto?
	public boolean removeAction(String className)
	{ // Puta mierda lo que hay que hacer para borrar un ComponentSBean
		Set<Component> newset = new TreeSet<Component>();
		boolean removed = false;
		for (Component action: actions)
		{
			if (action.getClassName().equals(className))
				removed = true;
			else
				newset.add(action);
		}
		actions = newset;
/*		if (removed)
		{
			boolean removefrompallete = true;
			it = activeActions.iterator();
			while (it.hasNext())
				if (((ComponentSBean)it.next()).getServiceName().equals(component.getServiceName()))
					removefrompallete = false;
			if (removefrompallete && paletteservices != null)
				paletteservices.remove(component.getServiceName());
		}*/
		return removed;
	}

/*	public void addAction(Component action)
	{
		actions.add(action);
	}
*/
/*	public Set getServicenames()
	{
		Set servicenames = new TreeSet();
		for (String className: activeActions)
				servicenames.add(className);
		return servicenames;
	}
	public Set<String> getServiceNames()
	{
		Set<String> servicenames = new TreeSet<String>();
		for (String className: activeActions)
				servicenames.add(className);
		return servicenames;
	}

	public String getServicenamesstring()
	{
		String servicenamesstring = new String();
		Iterator it = activeActions.iterator();
		while (it.hasNext())
			servicenamesstring += (((ComponentSBean)it.next()).getServiceName() + (it.hasNext() ? "," : ""));
		return servicenamesstring;
	}

	public int getServicecount()
	{
		return getServiceNames().size();
	}*/

/*	public HashSet getPaletteservices()
	{
		return paletteservices;
	}

	public boolean isServicespalette()
	{
		return paletteservices != null;
	}*/

/*	public boolean isServicespaletteactive()
	{
		return isServicespalette();
	}

	public boolean isIconservicespalette()
	{
		return iconservicespaletteactive;
	}*/

/*	public String getCsshref()
	{
		return csshref;
	}

	public void setCsshref(String value)
	{
		csshref = value;
	}
*/
	@OneToMany(mappedBy="portal",fetch=FetchType.EAGER,cascade={CascadeType.ALL})
	public Set<Role> getRoles()
	{
		return roles;
	}

	public void setRoles(Set<Role> roles)
	{
		this.roles = roles;
	}

	@Transient
	public Integer[] getRoleIds()
	{
		Integer[] roleIds = new Integer[roles.size()];
		int i = 0;
		for (Role role: roles)
		{
			roleIds[i] = role.getId();
			i++;
		}
		return roleIds;
	}

	@Transient
	public String[] getRoleNames()
	{
		String[] roleids = new String[roles.size()];
		int i = 0;
		for (Role role: roles)
		{
			roleids[i] = role.getName();
			i++;
		}
		return roleids;
	}

	@Transient
	public int getUserCount()
	{
		return users.size();
	}
	public boolean isRequiresSignupConfirmation()
	{
		return requiresSignupConfirmation;
	}

	public void setRequiresSignupConfirmation(boolean value)
	{
		requiresSignupConfirmation = value;
	}
	public void setUsers(Set<User> users)
	{
		this.users = users;
	}

	@OneToMany(mappedBy="portal",fetch=FetchType.LAZY, cascade={CascadeType.ALL})
	public Set<User> getUsers()
	{
		return users;
	}

	@Transient
	public void setProperty(String name, String value)
	{
		for (Property property: properties)
			if (property.getName().equals(name))
			{
				property.setValue(value);
				return;
			}
		properties.add(new Property(this,name,value));
	}
	
	@Transient
	public String getProperty(String name)
	{
	  if (properties!=null)
			for (Property property: properties)
				if (property.getName().equals(name))
					return property.getValue();
		return null;
	}
	
	@Transient
	public boolean getBooleanProperty(String propertyid)
	{
		try
		{
		 String property = getProperty(propertyid);
		 return property != null && new Boolean(property).booleanValue();
		} catch (Throwable t)
		{
		 return false;
		}
	}
	@Transient
	public Map<String,String> getPropertyMap()
	{
		Map<String,String> map = new HashMap<String,String>();
		for (Property property: properties)
			map.put(property.getName(),property.getValue());
		return map;
	}
/*	public void removeProperty(String name)
	{
		Set<Property> newProperties = new HashSet<Property>();
		for (Property property: properties)
			if (!property.getName().equals(name))
				newProperties.add(property);
		properties=newProperties;
	}*/
	@ManyToMany(targetEntity=Component.class,fetch=FetchType.EAGER)//TODO pasar a LAZY
	public Set<Component> getActions()
	{
		return actions;
	}
	public void setActions(Set<Component> actions)
	{
		this.actions=actions;
	}
	@Transient
	public Integer getIntegerProperty(String propertyid)
	{
		String property = getProperty(propertyid);
		try
		{
			if (property != null)
				return new Integer(property);
		} catch (NumberFormatException e)
		{
			if (log.isDebugEnabled())
				log.debug(property + " for " + propertyid + "@" + id + " can't be used as an Integer. Returning null");
			return null;
		}
		return null;
	}

	@Transient
	public Long getLongProperty(String propertyid)
	{
		String property = getProperty(propertyid);
		try
		{
			if (property != null)
				return new Long(property);
		} catch (NumberFormatException e)
		{
			if (log.isDebugEnabled())
				log.debug(property + " for " + propertyid + "@" + id + " can't be used as an Long. Returning null");
			return null;
		}
		return null;
	}

	@Transient
	public int getIntproperty(String portalid, String propertyid)
	{
		String property = getProperty(propertyid);
		try
		{
			if (property != null)
				return Integer.parseInt(property);
		} catch (NumberFormatException e)
		{
			if (log.isDebugEnabled())
				log.debug(property + " for " + propertyid + "@" + portalid + " can't be used as an Integer. Returning null");
			return 0;
		}
		return 0;
	}

	public void setProperties(Set<Property> properties)
	{
		this.properties = properties;
	}

	@OneToMany(mappedBy="portal",fetch=FetchType.EAGER,cascade={CascadeType.ALL})//TODO Pasar a LAZY
	public Set<Property> getProperties()
	{
		return properties;
	}

	public void setLastAccessed(Date lastAccessed)
	{
		this.lastAccessed = lastAccessed;
	}

	@Id
	public void setId(String id)
	{
		this.id = id;
	}

	@Transient
	public Collection<String> getServiceNames()
	{
		Collection<String> serviceNames = new TreeSet<String>();
		for (Component action: actions)
		{
			try
			{
				String serviceName = action.getServiceName();
					if (!Arrays.asList(PortalManagerBean.SYSTEM_SERVICE_NAMES).contains(serviceName) && !serviceNames.contains(serviceName))
						serviceNames.add(serviceName);
			} catch (NullPointerException e)
			{
				log.error(action.getClassName()+": "+e.getMessage());
			}
		}
		return serviceNames;
	}
	@Transient
	public String getGuestUserid()
	{
		return getProperty(GUEST_USER_ID_PROPERTY_NAME)==null?"guest":getProperty(GUEST_USER_ID_PROPERTY_NAME);
	}
	@Transient
	public String getAdminRoleName()
	{
		return getProperty(ADMIN_ROLE_NAME_PROPERTY_NAME)==null?"admin":getProperty(ADMIN_ROLE_NAME_PROPERTY_NAME);
	}
}
